package com.imdroid.carac.process;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.CommonDataKinds.StructuredName;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.RawContacts;
import android.util.Log;

import com.baidu.location.BDLocation;
import com.imdroid.carac.IMDroid;
import com.imdroid.carac.R;
import com.imdroid.carac.model.User;
import com.imdroid.carac.net.HttpHelper;

public class UserProcess extends BaseProcess {
	/**
	 * The string tag of this process
	 */
	private final static String TAG = "UserProcess";

	/**
	 * Get the user according the device IMET, the return string format is
	 * below:
	 * 
	 * [0] - "IM" - the succesfull tag [1] - 用户 Id [2] - 车机-imei [3] - 车机-sim卡号码
	 * [4] - 用户名称 [5] - 用户手机号码 [6] - 车型 [7] - 车牌号码 [8] - 车架号码 [9] - 发动机号 [10] 昵称
	 * [11] 购买日期 [12] 微博账号 [13] 微博令牌 [14] 微信账号 [15] 微信令牌 [16] 性别
	 * 
	 * @param IMEI
	 *            the number of device IMEI
	 * @param SIM
	 *            the number of device SIM Card
	 * @return the target user.
	 * @throws Exceptiom
	 */
	@SuppressLint("SimpleDateFormat")
	public User getUser(String IMEI, String SIM) throws Exception {
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("IMEI", IMEI));
		params.add(new BasicNameValuePair("SIM", SIM));
		String response = HttpHelper.execute("GetUserInfo", params);

		// 检查返回字串是否正确
		if (response == null)
			throw new Exception(IMDroid.getContext().getString(
					R.string.err_empty_http_response));

		if (response.trim().startsWith("EX"))
			throw new Exception(IMDroid.getContext().getString(R.string.error)
					+ response.substring(5, response.length()));

		if (!response.trim().startsWith("IM"))
			throw new Exception(IMDroid.getContext().getString(R.string.error)
					+ response);

		// 组成User对象
		User user = new User();
		// String[] item = response.split("%%");
		String[] item = split(response, "%%");
		user.setUser_id(Integer.valueOf(item[1]));
		user.setImei_number(item[2]);
		user.setSim_number(item[3]);
		user.setUser_name(item[4]);
		user.setMobile_phone(item[5]);
		user.setVechile_model(item[6]);
		user.setBoard_plate(item[7]);
		user.setFrame_number(item[8]);
		user.setEngine_number(item[9]);
		user.setNickname(item[10]);
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		if (item[11] != null && item[11].trim().length() > 0)
			user.setPurchase_date(sdf.parse(item[11]));
		user.setWeibo_account(item[12]);
		user.setWeibo_token(item[13]);
		user.setWeixin_account(item[14]);
		user.setWeixin_token(item[15]);
		user.setGender(item[16]);
		user.setTeam_access_code(item[19]);
		return user;
	}

	/**
	 * Post the user change to server
	 * 
	 * @throws IOException
	 */
	// public void postUser(User user) throws IOException {
	public void postUser(User user) {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("user_id", user.getUser_id() + ""));
		params.add(new BasicNameValuePair("user_name", user.getUser_name()));
		params.add(new BasicNameValuePair("mobile_phone", user
				.getMobile_phone()));
		params.add(new BasicNameValuePair("sim_number", user.getSim_number()));
		params.add(new BasicNameValuePair("vechile_model", user
				.getVechile_model()));
		params.add(new BasicNameValuePair("board_plate", user.getBoard_plate()));
		params.add(new BasicNameValuePair("frame_number", user
				.getFrame_number()));
		params.add(new BasicNameValuePair("engine_number", user
				.getEngine_number()));
		params.add(new BasicNameValuePair("nickname", user.getNickname()));
		params.add(new BasicNameValuePair("weibo_account", user
				.getWeibo_account()));
		params.add(new BasicNameValuePair("nickname", user.getNickname()));
		params.add(new BasicNameValuePair("access_code", user
				.getTeam_access_code()));
		try {
			HttpHelper.execute("UpdateUserInfo", params).trim();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * post the current user location
	 * 
	 * @param location
	 *            the location of the user
	 * @return if success or not
	 * @throws Exception
	 */
	public boolean postUserLocation(BDLocation location, long startLogTime)
			throws Exception {
		String imei = IMDroid.getDeviceIMEI();

		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("IMEI", imei));
		params.add(new BasicNameValuePair("lat", location.getLatitude() + ""));
		params.add(new BasicNameValuePair("lon", location.getLongitude() + ""));
		params.add(new BasicNameValuePair("startTime", startLogTime + ""));

		return "1".equals(HttpHelper.execute("Location", params).trim());
	}

	/**
	 * Get the last version number from the server
	 * 
	 * @return The last version from the server
	 * @throws Exception
	 */
	public String getLastVersion() throws Exception {
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("type", "C"));
		return HttpHelper.execute("CheckVersion", params).trim();
	}

	/**
	 * synchronize the contract to server
	 * 
	 * @param context
	 *            the application context
	 * @throws Exception
	 */
	public void synchronizeContact(Context context) throws Exception {
		// 从服务器上拿到联系人列表
		Map<String, String> contacts = retrieveAllContact(IMDroid.getUser());
		// 首先删除所有联系人
		deleteAllContacts(context);

		// 插入新的联系人
		for (String phoneNumber : contacts.keySet()) {
			String displayName = contacts.get(phoneNumber);
			ContentValues values = new ContentValues();

			Uri rawContactUri = context.getContentResolver().insert(
					RawContacts.CONTENT_URI, values);
			long rawContactId = ContentUris.parseId(rawContactUri);

			// 往data表里写入姓名数据
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE); // 内容类型
			values.put(StructuredName.GIVEN_NAME, displayName);
			context.getContentResolver().insert(
					android.provider.ContactsContract.Data.CONTENT_URI, values);

			// 往data表里写入电话数据
			values.clear();
			values.put(Data.RAW_CONTACT_ID, rawContactId);
			values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
			values.put(Phone.NUMBER, phoneNumber);
			values.put(Phone.TYPE, Phone.TYPE_MOBILE);
			context.getContentResolver().insert(
					android.provider.ContactsContract.Data.CONTENT_URI, values);

			Log.d(TAG, displayName + " " + phoneNumber);
		}
	}

	/**
	 * retrieve all the contact from server
	 * 
	 * @param user
	 *            the target user
	 * @throws Exception
	 * 
	 */
	private Map<String, String> retrieveAllContact(User user) throws Exception {
		// 从服务器上读取改车机用户的联系人列表
		ArrayList<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("user_id", user.getUser_id() + ""));
		String objectString = HttpHelper.execute("SyncContractGet", params)
				.trim();
		JSONArray jsonArray = new JSONArray(objectString);

		Map<String, String> map = new HashMap<String, String>();
		for (int i = 0; i < jsonArray.length(); ++i) {
			JSONObject contactJson = (JSONObject) jsonArray.get(i);
			String phoneNumber = contactJson.getString("phone_number");
			String displayName = contactJson.getString("display_name");
			map.put(phoneNumber, displayName);
		}
		return map;
	};

	/**
	 * Delete all the contacts
	 * 
	 * @throws Exception
	 */
	private void deleteAllContacts(Context context) throws Exception {
		// 获取联系人
		Collection<Long> ids = new ArrayList<Long>();
		Cursor cusror = context.getContentResolver().query(
				ContactsContract.Contacts.CONTENT_URI, null, null, null, null);
		if (!cusror.moveToFirst()) {
			cusror.close();
			return;
		}

		int idColumn = cusror.getColumnIndex(ContactsContract.Contacts._ID);
		// 循环遍历所有联系人
		do {
			ids.add(cusror.getLong(idColumn));
			Log.d(TAG, "Adding the id" + cusror.getLong(idColumn));
		} while (cusror.moveToNext());
		cusror.close();
		// 循环遍历所有联系人
		for (Long id : ids) {
			context.getContentResolver().delete(
					ContentUris.withAppendedId(RawContacts.CONTENT_URI, id),
					null, null);
			Log.d(TAG, "Remove the id - " + id);
		}
	}

	/**
	 * Broadcast the voice to all team member
	 * 
	 * @param fileName
	 *            the file name of the voice
	 */
	public void uploadPitcure(String filePath, String fileName)
			throws Exception {
		HttpURLConnection httpURLConnection = null;
		DataOutputStream dataOutputStream = null;
		FileInputStream fileInputStream = null;
		DataInputStream dataInputStream = null;

		try {
			// 准备文件
			File file = new File(filePath + "/" + fileName);
			Log.d(TAG, "file--" + filePath + "/" + fileName);
			fileInputStream = new FileInputStream(file);

			// 准备HTTP connection
			httpURLConnection = (HttpURLConnection) new URL(
					HttpHelper.webAddress + "UploadPicture").openConnection();
			httpURLConnection.setDoOutput(true);
			httpURLConnection.setDoInput(true);
			httpURLConnection.setRequestMethod("POST");
			httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
			httpURLConnection.setRequestProperty("Charset", "UTF-8");
			httpURLConnection.setUseCaches(false);
			httpURLConnection.setRequestProperty("Content-Type",
					"multipart/form-data;boundary=1L");

			// 写入内容
			dataOutputStream = new DataOutputStream(
					httpURLConnection.getOutputStream());
			dataOutputStream.writeUTF(IMDroid.getUser().getUser_id() + "");
			dataOutputStream.writeUTF(fileName);
			int len = 0;
			byte[] buf = new byte[1024];
			while ((len = fileInputStream.read(buf)) != -1) {
				dataOutputStream.write(buf, 0, len);
				Log.d(TAG, "Upload......");
			}
			fileInputStream.close();
			dataOutputStream.flush();

			// 获取response
			dataInputStream = new DataInputStream(
					httpURLConnection.getInputStream());
			// String res = dataInputStream.readLine() + "";
			Log.d(TAG, "Upload finish");
			// Log.d(TAG, "Upload finish - " + res);
			dataOutputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
			PlaySoundProcess.playSound(PlaySoundProcess.wrong);
			Log.d(TAG, "Upload false - " + e.getMessage());
			throw e;
		} finally {

			if (dataInputStream != null) {
				try {
					dataInputStream.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (dataOutputStream != null) {
				try {
					dataOutputStream.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (httpURLConnection != null) {
				try {
					httpURLConnection.disconnect();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			if (fileInputStream != null) {
				try {
					fileInputStream.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * Sent the sms
	 * 
	 * @param phoneNumber
	 *            the phone number
	 * @param messeageText
	 *            the message text
	 * @throws Exception
	 */
	public void sendSMS(String phoneNumber, String messeageText)
			throws Exception {
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("mobilePhone", phoneNumber));
		params.add(new BasicNameValuePair("content", messeageText));
		params.add(new BasicNameValuePair("userId", IMDroid.getUser()
				.getUser_id() + ""));
		try {
			HttpHelper.execute("SMS", params).trim();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Return if the server is pingable
	 * 
	 */
	public boolean ping() {
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		try {
			String str = HttpHelper.execute("ping.txt", params).trim();
			return "1".equals(str.trim());
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	/**
	 * Start the match status
	 * 
	 * @param location
	 *            the current location
	 * @param matchCode
	 *            the match code
	 * @return if it is success
	 * @throws Exception
	 */
	public boolean startMatchStatus(BDLocation location, String matchCode)
			throws Exception {
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("matchCode", matchCode));
		params.add(new BasicNameValuePair("current_lat", location.getLatitude()
				+ ""));
		params.add(new BasicNameValuePair("current_lon", location
				.getLongitude() + ""));
		params.add(new BasicNameValuePair("device_id", IMDroid.getUser()
				.getUser_id() + ""));

		return HttpHelper.execute("MatchCodeAdd", params).trim().equals("1");
	}

	/**
	 * Stop the match code status
	 * 
	 * @return if it is succcess.
	 * @throws Exception
	 */
	public boolean stopMatchStatus() throws Exception {
		List<BasicNameValuePair> params = new ArrayList<BasicNameValuePair>();
		params.add(new BasicNameValuePair("device_id", IMDroid.getUser()
				.getUser_id() + ""));

		return HttpHelper.execute("MatchCodeRemove", params).trim().equals("1");
	}

}
